﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Util
{
    public class DataConv
    {
        public static string ToText(byte[] buffer)
        {
            return Encoding.Default.GetString(buffer); 
        }

        public static string ToHex(byte[] dataBuf, int offset, int length)
        {
            //字节数组转化成十六进制的字符串形式，以空格隔开。
            if (dataBuf == null || dataBuf.Length < 1) return string.Empty;

            StringBuilder sb = new StringBuilder();

            for (int i = offset; i < dataBuf.Length; i++)
            {
                if ((i - offset) > length) break;
                sb.Append(Convert.ToString(dataBuf[i], 16).PadLeft(2, '0'));
                sb.Append(" ");
            }

            sb.Remove(sb.Length - 1, 1);
            return sb.ToString().ToUpper();
        }

        public static string ToHex(byte[] dataBuf)
        {
            //字节数组转化成十六进制的字符串形式，以空格隔开。
            if (dataBuf == null || dataBuf.Length < 1) return string.Empty;

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < dataBuf.Length; i++)
            {
                sb.Append(Convert.ToString(dataBuf[i], 16).PadLeft(2, '0'));
                sb.Append(" ");
            }

            sb.Remove(sb.Length - 1, 1);
            return sb.ToString().ToUpper();
        }

        public static string ToHexString(byte[] dataBuf)
        {
            //字节数组转化成十六进制的字符串形式，以空格隔开。
            if (dataBuf == null || dataBuf.Length < 1) return string.Empty;

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < dataBuf.Length; i++)
            {
                sb.Append(Convert.ToString(dataBuf[i], 16).PadLeft(2, '0'));
                sb.Append(" ");

                if (((i + 1) % 32 == 0))
                {
                    sb.Append("\r\n");
                }
                else if (((i + 1) % 16 == 0))
                {
                    sb.Append("- ");
                }
                else if (((i + 1) % 8 == 0))
                {
                    sb.Append(" ");
                }
            }

            sb.Remove(sb.Length - 1, 1);
            return sb.ToString().ToUpper();
        }

        public static string ToHexStr(byte[] buffer)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < buffer.Length; i++)
            {
                sb.Append(string.Format("{0:X2} ", buffer[i]));
            }

            if (sb.Length > 0) sb.Remove(sb.Length - 1, 1);

            return sb.ToString();
        }

        public static string ToHexStr(byte[] buffer, string split)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < buffer.Length; i++)
            {
                sb.Append(string.Format("{0:X2}", buffer[i]));

                if (!string.IsNullOrEmpty(split)) sb.Append(split);

            }

            if (!string.IsNullOrEmpty(split) && sb.Length > 0 )
            {
                sb.Remove(sb.Length - split.Length, split.Length);
            }

            return sb.ToString();
        }

        public static byte[] FromHexStr(string value)
        {
            value = value.Replace(" ", "");
            byte[] buffer = new byte[value.Length / 2];

            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = Convert.ToByte(value.Substring(i * 2, 2), 16);
            }

            return buffer;
        }

        /// <summary>
        /// 字符串到BCD码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static byte[] StrToBCD(string text)
        {
            byte[] buffer = new byte[text.Length / 2];
            for (int i = 0; i < text.Length; i += 2)
            {
                byte hi = (byte)(text[i] - 0x30);
                byte lo = (byte)(text[i + 1] - 0x30);
                buffer[i / 2] = (byte)((hi << 4) | lo);
            }

            return buffer;
        }

        /// <summary>
        /// BCD码转换为字符串
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string BCDToStr(byte[] buffer, int index, int length)
        {
            StringBuilder sb = new StringBuilder();
            int count = index + length;
            for (int i = index; i < count; i++)
            {
                sb.Append((char)((buffer[i] >> 4) + 0x30));
                sb.Append((char)((buffer[i] & 0x0F) + 0x30));
            }

            return sb.ToString();
        }

        public static string BCDToStr(byte[] buffer)
        {
            return BCDToStr(buffer, 0, buffer.Length);
        }

        /// <summary>
        /// Hex转换成BCD码
        /// </summary>
        /// <param name="hex"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static ulong HexToBCD(ulong hex, uint num)
        {
            int i;
            ulong pdiv, pmul;

            byte[] tmp = new byte[num];
            pdiv = hex;
            for (i = 0; i < num; i++)
            {
                tmp[i] = (byte)(pdiv % 10);
                pdiv = pdiv / 10;
            }
            pmul = 1;
            pdiv = 0;
            for (i = 0; i < num; i++)
            {
                pdiv = pdiv + pmul * tmp[i];
                pmul = pmul * 0x10;
            }
            return pdiv;
        }


        /// <summary>
        /// 功率单位转换，将dbm转换为W
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static double dbmToW(double value)
        {
            //dbm = 10 * lg(W * 1000);
            //W*1000 = pow(dbm / 10);
            double result = Math.Pow(10, value / 10) / 1000;

            return result;
        }

        /// <summary>
        /// 将小数转换成指数表示
        /// </summary>
        /// <param name="floatStr"></param>
        /// <returns></returns>
        public static string FloatToExpo(string floatStr)
        {
            StringBuilder resultStr = new StringBuilder();
            resultStr.Append(floatStr.Substring(0, 4));
            if (floatStr.IndexOf('-') != -1)
                resultStr.Append("×10ˉ");
            else
                resultStr.Append("×10+");
            int index = floatStr.IndexOf('E');
            string str = floatStr.Substring(index + 2);
            int expo = Convert.ToInt16(str);
            resultStr.Append(expo.ToString());
            return resultStr.ToString();
        }

        /// <summary>
        /// 将数组转换为字符串
        /// </summary>
        /// <param name="array">数组</param>
        /// <param name="fmtStr">字符串格式</param>
        /// <returns></returns>
        public static string ArrayToString(double[] array, string fmtStr)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in array)
            {
                sb.Append(item.ToString(fmtStr));
                sb.Append(", ");
            }
            if (sb.Length > 0) sb.Remove(sb.Length - 2, 2);
            return sb.ToString();
        }

        /// <summary>
        /// 将数组转换成字符串
        /// </summary>
        /// <param name="array">数组</param>
        /// <returns></returns>
        public static string ArrayToString(double[] array)
        {
            return ArrayToString(array, "0.0");
        }

        /// <summary>
        /// 获取字符串的从起始开始的数字部分
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static double GetStrNum(string value)
        {
            try
            {
                value = value.Trim();
                for (int i = 0; i < value.Length; i++)
                {
                    if (Char.IsLetter(value[i]))
                    {
                        value = value.Substring(0, i);
                        return double.Parse(value);
                    }
                }
            }
            catch
            {
            }

            return 0;
        }

        public static double uV_To_dBuV(double value)
        {
            return Math.Round(20 * Math.Log10(value), 1);
        }

        public static double uV_To_dBm(double value)
        {
            return Math.Round(20 * Math.Log10(value) - 107, 1);
        }

        /// <summary>
        /// 将32位整数转换到字节数组
        /// </summary>
        /// <param name="dwNum">32位整数数据</param>
        /// <param name="mData">要转换到的字节数组</param>
        /// <param name="index">转换到字节数组的位置</param>
        public static void UInt32toBytes(UInt32 dwNum, byte[] mData, int index)
        {
            mData[index] = (byte)dwNum;
            mData[index + 1] = (byte)(dwNum >> 8);
            mData[index + 2] = (byte)(dwNum >> 16);
            mData[index + 3] = (byte)(dwNum >> 24);
        }


        /// <summary>
        /// 将字节数组的数据转换到32位整数
        /// </summary>
        /// <param name="mData">字节数组</param>
        /// <param name="index">开始转换的字节数组位置</param>
        /// <returns>32位整数</returns>
        public static UInt32 BytestoUint32(byte[] mData, int index)
        {
            uint num = (UInt32)(mData[index] | (mData[index + 1] << 8) | (mData[index + 2] << 16) | (mData[index + 3] << 24));
            return num;
        }

    }

    public class UnixTime
    {
        static readonly DateTime StartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));


        public static DateTime FromInt32(int time)
        {
            return StartTime.AddSeconds(time);
        }

        public static int ToInt32(DateTime time)
        {
            if (time == DateTime.MinValue) return 0;

            return (int)((time - StartTime).TotalSeconds);
        }
    }

    public class BCD
    {
        public static uint ToDEC(uint num)
        {
            return convert(num, 0x10, 10);
        }

        public static uint FromDEC(uint num)
        {
            return convert(num, 10, 0x10);
        }

        private static uint convert(uint num, uint divider, uint factor)
        {
            uint remainder = 0, quotient = 0, result = 0;
            remainder = num % divider;
            quotient = num / divider;
            if (!(quotient == 0 && remainder == 0))
                result += convert(quotient, divider, factor) * factor + remainder;
            return result;
        }
    }
}
